<?php
/**
 * Created by PhpStorm.
 * User: ZhangYinxian
 * Date: 2016-10-16
 * Time: 17:47
 */

namespace app\index\logic;

use think\Db;
use app\index\logic\Amino as AminoLogic;
class DNATranslate
{
    private $mHasError;
    private $mMessage;

    /**
     * @param $dna dna序列
     * @return array result结果
     */
    public function getDNAResult($dna){

        $dna_pattern = '/[A|G|T|C|U]+/';
        $result = preg_match_all($dna_pattern, $dna, $items);
        $dna_correct = false;
        if($result==1 && count($items[0])==1){
            $dna_correct = true;
        }
        if($dna_correct==false){
            return $this->setMessage('DNA序列中包含了AGTCU以外的字符');
        }
        $dna_standard_data = [
            'A'=>'A',
            'G'=>'G',
            'T'=>'T',
            'U'=>'U',
            'C'=>'C'
        ];
        $amino_logic = new AminoLogic();
        $amino_result = $amino_logic->analyze($dna, $dna_standard_data);
        if($amino_result['has_error']){
            return $this->setMessage($amino_result['message']);
        }

        $original_dna = $amino_result['amino_detail'];
        $reverse_dna = [];

        foreach ($original_dna as $tmp_dna){
            switch ($tmp_dna){
                case 'U':
                    array_push($reverse_dna, 'T');
                    break;
                default:
                    array_push($reverse_dna, $tmp_dna);
                    break;
            }
        }

        $sequence1 = [];
        $sequence2 = [];

        $library_dna_amino = Db::name('LibraryDnaAmino');
        $library_dna_amino_data = $library_dna_amino->select();
        $library_dna_amino_data_map = array2map($library_dna_amino_data, 'dna');

        $reverse_dna_count = count($reverse_dna);
        for($i=0; $i<3; $i++){
            if (($reverse_dna_count-$i)<3) break;
            $tmp_sequence1='';
            for($index=$i; $index<$reverse_dna_count; $index+=3){
                $sub_dna = array_slice($reverse_dna, $index, 3);
                $str_dna = implode('', $sub_dna);
                if(isset($library_dna_amino_data_map[$str_dna])){
                    $tmp_sequence1 = $tmp_sequence1 . $library_dna_amino_data_map[$str_dna]['amino'];
                }else{
                    break;
                }
            }
            array_push($sequence1, $tmp_sequence1);
        }

        $reverse_dna2 = array_reverse($reverse_dna);
        $reverse_dna_count2 = count($reverse_dna2);
        for($i=0; $i<3; $i++){
            if (($reverse_dna_count-$i)<3) break;
            $tmp_sequence2 = '';
            for($index=$i; $index<$reverse_dna_count2; $index+=3){
                $sub_dna = array_slice($reverse_dna2, $index, 3);
                $str_dna = implode('', $sub_dna);
                if(isset($library_dna_amino_data_map[$str_dna])){
                    $tmp_sequence2 = $tmp_sequence2 . $library_dna_amino_data_map[$str_dna]['amino'];
                }else{
                    break;
                }
            }
            array_push($sequence2, $tmp_sequence2);
        }

        return [
            'has_error'=>$this->mHasError,
            'message'=>$this->mMessage,
            'sequence1'=>$sequence1,
            'sequence2'=>$sequence2
        ];

    }

    public function setMessage($message, $hasError=true){
        $this->mHasError = $hasError;
        $this->mMessage = $message;

        return [
            'has_error'=>$this->mHasError,
            'message'=>$this->mMessage
        ];
    }
}